﻿#light

module MapReduceFSharpMethod

open System
open System.Collections.Generic
open System.Runtime.InteropServices

let map (content : string) =

    let entryCriteria (content : string) i =
        let ch = int content.[i]
        ((ch > 47 && ch < 58) || (ch > 96 && ch < 123) || (ch > 64 && ch < 91) || ch = 95 || ch = 45 || ch = 39)

    let addEntries (content : string) i count (entries : List<String>) =
        if count > 0 then
            entries.Add(content.Substring(i - count, count))
        entries.Add(content.Substring(i, 1))
        entries

    let rec functionMapRec (content : string) i count entries : List<string> =
        match i with
        | _ when i = content.Length -> entries
        | _ when entryCriteria content i -> functionMapRec content (i+1) (count+1) entries
        | _ -> functionMapRec content (i+1) 0 (addEntries content i count entries)
        
    let stringEntries = functionMapRec content 0 0 (new List<String>())
    stringEntries.Sort(compare)
    stringEntries
    
  
let reduce (stringEntries : List<String>) =
    let rec functionReduceRec (stringEntries : List<String>) prevEntry (stringTotal : Dictionary<string, int>) i count =
        if i = stringEntries.Count then
            stringTotal.Add(prevEntry, count)
            stringTotal
        else
            let entry = stringEntries.[i]
            if entry = prevEntry then
                functionReduceRec stringEntries entry stringTotal (i+1) (count+1)
            else
                stringTotal.Add(prevEntry, count)
                functionReduceRec stringEntries entry stringTotal (i+1) 1
                
    functionReduceRec stringEntries stringEntries.[0] (new Dictionary<String, int>()) 1 1
